package org.example.day04;

import java.util.Scanner;

/**
 * @author zlxad
 * @version 1.0
 * @description: TODO +
 * <p>  某公司部门需要派遣员工去国外做项目。现在，代号为x的国家和代号为y的国家分别需要cntx名和cnty名员工。部门每个员工有一个员工号(1,2,3……)，工号连续，从1开始。 </p> <p>  部长派遣员工的规则： </p> <ul>  <li>   规则1、从[1,k]中选择员工派遣出去    <li>   规则2、编号为x的倍数的员工不能去x国，编号为y的倍数的员工不能去y国   </ul> <p>  问题：<br> 找到最小的k，使得可以将编号在[1,k]中的员工分配给x国和y国，且满足x国和y国的需求 </p>
 *
 * 某公司部门需要派遣员工去国外做项目。现在，代号为x的国家和代号为y的国家分别需要cntx名和cnty名员工。部门每个员工有一个员工号(1,2,3……)，工号连续，从1开始。
 * 部长派遣员工的规则：
 * 规则1、从[1,k]中选择员工派遣出去
 * 规则2、编号为x的倍数的员工不能去x国，编号为y的倍数的员工不能去y国
 * 问题： 找到最小的k，使得可以将编号在[1,k]中的员工分配给x国和y国，且满足x国和y国的需求
 * @date 2024/3/11 15:22
 */
public class test067 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        // 定义长整型变量x，y，cntX，cntY
        long x, y, cntX, cntY;

        // 读取输入值，x和y分别代表两个国家的代号，cntX和cntY分别代表两个国家需要的员工数
        x = scanner.nextLong();
        y = scanner.nextLong();
        cntX = scanner.nextLong();
        cntY = scanner.nextLong();

        // 初始化搜索范围的左右边界，left为两国需要的员工总数，right为一个较大的预设值
        long left = cntX + cntY, right = 1000000000;

        // 使用二分搜索算法来找到满足条件的最小的k值
        while (left <= right) {
            long mid = left + (right - left) / 2; // 计算中间值
            if (isValid(x, y, cntX, cntY, mid)) {
                // 如果中间值满足条件，则尝试向左侧搜索更小的满足条件的值
                right = mid - 1;
            } else {
                // 如果中间值不满足条件，则向右侧搜索
                left = mid + 1;
            }
        }

        System.out.println(left); // 输出找到的满足条件的最小k值
        scanner.close(); // 关闭扫描器资源
    }

    /**
     * 判断给定的k值是否可以满足两个国家的员工需求
     *
     * @param x    国家X的代号
     * @param y    国家Y的代号
     * @param cntX 国家X需要的员工数量
     * @param cntY 国家Y需要的员工数量
     * @param k    当前考虑的员工编号范围上限
     * @return     是否可以满足条件
     */
    private static boolean isValid(long x, long y, long cntX, long cntY, long k) {
        long cantGoX = k / x; // 计算不能去X国的员工数
        long cantGoY = k / y; // 计算不能去Y国的员工数
        long cantGoBoth = k / (x * y); // 计算同时不能去X国和Y国的员工数

        // 计算实际还需要为X国和Y国分配的员工数
        long actualNeedX = Math.max(0, cntX - (cantGoY - cantGoBoth));
        long actualNeedY = Math.max(0, cntY - (cantGoX - cantGoBoth));

        // 计算在避免了不能去某国的员工后，剩余可供分配的员工数
        long available = k - cantGoX - cantGoY + cantGoBoth;

        // 判断这些可用员工是否足够满足两个国家的需求
        return actualNeedX + actualNeedY <= available;
    }
}


